#include "children.h"

/* knows about the fact that the default value for "rel" is "alternate" */
static apr_xml_elem * find_link(apr_xml_doc * doc, apr_xml_elem * e,
				char * rel, char * * href_p) {
    char * * namespaces = (char * *) doc->namespaces->elts;
    apr_xml_elem * child;
    char * href = NULL;

    for (child = e->first_child; child; child = child->next) {
	apr_xml_attr * a;
	char * child_rel = "alternate";

	if (child->ns == APR_XML_NS_NONE ||
	        strcmp(namespaces[child->ns], ATOM_NS) != 0 ||
	            strcmp(child->name, "link") != 0)
	    continue;
	
	for (a = child->attr; a; a = a->next)
	    if (a->ns == APR_XML_NS_NONE) {
		if (strcmp(a->name, "rel") == 0)
		    child_rel = (char *) a->value;
		else if (strcmp(a->name, "href") == 0)
		    href = (char *) a->value;
	    }

	if (strcmp(rel, child_rel) == 0) {
	    if (href_p)
		*href_p = href;
	    return child;
	}
    }
    return NULL;
}

apr_xml_elem * atom_xml_link_el(apr_xml_doc * doc, apr_xml_elem * e,
				char * rel) {
    return find_link(doc, e, rel, NULL);
}

char * atom_xml_link_href(apr_xml_doc * doc, apr_xml_elem * e, char * rel) {
    char * href;
    return (find_link(doc, e, rel, &href)) ? href : NULL;
}

apr_xml_elem * atom_xml_child(apr_xml_doc * doc,
			      apr_xml_elem * e, char * child_ns,
			      char * child_name) {
    char * name[] = { child_name, NULL };
    apr_xml_elem * ret = NULL;
    apr_xml_elem * * a[] = { &ret };

    atom_xml_children(doc, e, child_ns, name, a);
    return ret;
}

void atom_xml_children(apr_xml_doc * doc, apr_xml_elem * e,
		       char * ns, char * names[],
		       apr_xml_elem * * children[]) {
    char * * namespaces = (char * *) doc->namespaces->elts;
    apr_xml_elem * child;

    for (child = e->first_child; child; child = child->next) {
	int i;

	if (ns == NULL) {
	    if (child->ns != APR_XML_NS_NONE)
		continue;
	} else {
	    if (child->ns == APR_XML_NS_NONE ||
	           strcmp(namespaces[child->ns], ns) != 0)
		    continue;
	}

	/* O(N**2), sigh */
	for (i = 0; names[i]; i++)
	    if (strcmp(names[i], child->name) == 0)
		*children[i] = child;
    }
}

